from copy import deepcopy

from django.db import transaction
from rest_framework import serializers
from mineral.models import *


# 更改大类 库存
def alter_mineraltype_quantity(inventory):
    mineral_type = inventory.product.mineral_type
    inventory_obj = Inventory.objects.filter(product__mineral_type=inventory.product.mineral_type)
    total_quantity = 0
    for i in inventory_obj:
        total_quantity += i.total_quantity
        # print(i.total_quantity)
        # print(i.product.name)
    mineral_type.quantity = total_quantity
    mineral_type.save()


class MineralTypeSerializer(serializers.ModelSerializer):
    class Meta:
        model = MineralType
        exclude = ('create_time', 'update_time')


class ListMineralTypeSerializer(serializers.ModelSerializer):
    class Meta:
        model = MineralType
        exclude = ('create_time', 'update_time')
        depth = 1


class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        # fields = '__all__'
        # fields = ['name', 'create_time']
        exclude = ('create_time', 'update_time')
        depth = 1


class EditProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        exclude = ('create_time', 'update_time')


class ListProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        exclude = ('create_time', 'update_time')
        depth = 1


class InventoryPerformSerializer(serializers.ModelSerializer):
    class Meta:
        model = InventoryPerform
        exclude = ('create_time', 'update_time')

    @transaction.atomic()
    def create(self, validated_data):
        instance = super().create(validated_data)
        try:
            # 更改库存
            inventory = Inventory.objects.get(product=instance.product)
            inventory.plant_quantity += instance.quantity
            inventory.save()
            # 更改领用后库存
            instance.inventory_after_requisition = inventory.plant_quantity
            instance.save()
            # 更改大类库存
            alter_mineraltype_quantity(inventory)
            return instance
        except Exception as e:
            if str(e) == 'Inventory matching query does not exist.':
                raise serializers.ValidationError({'message': instance.product.name + '没有初始化库存'})
            raise serializers.ValidationError({'message': str(e)})


class ListInventoryPerformSerializer(serializers.ModelSerializer):
    class Meta:
        model = InventoryPerform
        exclude = ('update_time',)
        depth = 1


class InventorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Inventory
        exclude = ('create_time', 'update_time')

    @transaction.atomic()
    def create(self, validated_data):
        print('''validated_data['product']''')
        print(validated_data['product'].__dict__)

        q = Inventory.objects.filter(product=validated_data['product'])
        print('len(q)', len(q))
        if len(q) > 0:
            raise serializers.ValidationError({'message': q[0].product.name + '库存已经初始化，不能初始化两次'})
        # 更改Inventory
        instance = super().create(validated_data)
        instance.save()
        # 更改大类库存
        alter_mineraltype_quantity(instance)
        # 初始化的同时 需要更新 统计分组库存
        if instance.product.product_group is not None:
            alter_productgroup_quantity(instance.product.product_group)
        return instance

    @transaction.atomic
    def update(self, instance, validated_data):
        # 更改Inventory
        super().update(instance, validated_data)
        # 更改大类库存
        alter_mineraltype_quantity(instance)

        # 更新的同时 需要更新 统计分组库存
        if instance.product.product_group is not None:
            alter_productgroup_quantity(instance.product.product_group)
        return instance


class ListInventorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Inventory
        fields = ['total_quantity', 'plant_quantity', 'port_quantity', 'not_arrival_port_quantity', 'safe_day',
                  'daily_consumption', 'product', 'id', 'not_arrival_port_note']
        # exclude = ('create_time', 'update_time')

        depth = 1


class ProductionPlanSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProductionPlan
        exclude = ('create_time', 'update_time')


class ListProductionPlanSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProductionPlan
        exclude = ('create_time', 'update_time')
        depth = 1


class PurchasePlanSerializer(serializers.ModelSerializer):
    class Meta:
        model = PurchasePlan
        exclude = ('create_time', 'update_time')

    @transaction.atomic()
    def create(self, validated_data):
        q = PurchasePlan.objects.filter(product=validated_data['product'])
        print('len(q)', len(q))
        if len(q) > 0:
            raise serializers.ValidationError({'message': q[0].product.name + '已存在采购计划'})
        instance = super().create(validated_data)
        instance.save()
        return instance


class ListPurchasePlanSerializer(serializers.ModelSerializer):
    class Meta:
        model = PurchasePlan
        exclude = ('create_time', 'update_time')
        depth = 1


def alter_productgroup_quantity(instance):
    query = Inventory.objects.filter(product__product_group=instance)
    # 重置分组库存 重新统计分组库存
    instance.plant_quantity = 0
    instance.in_plant_quantity = 0
    for i in query:
        # 计算总库存
        instance.plant_quantity += i.total_quantity
        # 计算 厂内总库存 厂内库存
        instance.in_plant_quantity = instance.in_plant_quantity + i.plant_quantity + i.port_quantity
    instance.save()


class ProductGroupSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProductGroup
        fields = ['type_name', 'product_set', 'id', 'daily_consumption', 'requirement_planning', ]

    def create(self, validated_data):
        instance = super().create(validated_data)
        # 更改分组库存
        alter_productgroup_quantity(instance)
        return instance

    def update(self, instance, validated_data):
        instance = super().update(instance, validated_data)

        # 更改分组库存
        alter_productgroup_quantity(instance)
        return instance
